package com.sl.biz.modular.ide.service.impl;

import cn.dev33.satoken.context.mock.SaTokenContextMockUtil;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.thread.ExecutorBuilder;
import cn.hutool.core.util.StrUtil;
import com.google.common.collect.Lists;
import com.sl.auth.core.enums.SaClientTypeEnum;
import com.sl.auth.core.util.StpCompositeUtil;
import com.sl.biz.modular.ide.domain.response.IdeListVO;
import com.sl.biz.modular.ide.service.IdeBizService;
import com.sl.biz.modular.job.dao.entity.JobConfigDO;
import com.sl.biz.modular.job.service.JobConfigBizService;
import com.sl.biz.modular.office.dao.domain.entity.OfficeRecordDO;
import com.sl.biz.modular.office.service.OfficeRecordBizService;
import com.sl.biz.modular.process.controller.request.SquareLakeProcessQueryByConditionRequest;
import com.sl.biz.modular.process.controller.response.ProcessSimpleVO;
import com.sl.biz.modular.process.controller.response.ProcessVersionVO;
import com.sl.biz.modular.process.dao.domain.entity.ProcessVersionDO;
import com.sl.biz.modular.process.service.ProcessConfigBizService;
import com.sl.biz.modular.process.service.ProcessVersionBizService;
import com.sl.biz.modular.restapi.dao.entity.ApiConfigDO;
import com.sl.biz.modular.restapi.service.ApiConfigBizService;
import com.sl.biz.modular.views.dao.domain.entity.ViewConfigDO;
import com.sl.biz.modular.views.service.ViewConfigBizService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
@Slf4j
public class IdeBizServiceImpl implements IdeBizService {

    private final OfficeRecordBizService officeRecordBizService;

    private final ViewConfigBizService viewConfigBizService;

    private final JobConfigBizService jobConfigBizService;

    private final ApiConfigBizService apiConfigBizService;

    private final ProcessConfigBizService processBizService;

    private final ProcessVersionBizService versionBizService;

    private static final ThreadPoolExecutor EXECUTOR;

    static {
        ExecutorBuilder builder = ExecutorBuilder.create();
            builder.setCorePoolSize(8);
        EXECUTOR= builder.build();
    }

    @Override
    public List<IdeListVO> list(String groupId, String productId, String processId) {


        SaClientTypeEnum saClientTypeEnum = StpCompositeUtil.get();
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        List<IdeListVO> result = Lists.newArrayList();
        String tokenValue = StpCompositeUtil.getTokenValue();
        List<String> typeList = Lists.newArrayList();
        typeList.add("whiteboard");
        typeList.add("mind");
        typeList.add("word");
        typeList.add("excel");
        typeList.add("view");
        typeList.add("job");
        typeList.add("api");
        typeList.add("process");
        typeList.add("processVersion");

        List<Future<List<IdeListVO>>> futureList = typeList.stream().map(d -> EXECUTOR.submit(() -> {
            //登陆信息透出
            StpCompositeUtil.appendLogin(saClientTypeEnum, servletRequestAttributes);
//            StpCompositeUtil.login(loginId);
            SaTokenContextMockUtil.setMockContext();

            StpUtil.setTokenValueToStorage(tokenValue);
            if (d.equals("view")) {
                ViewConfigDO viewConfigDO = new ViewConfigDO();
                viewConfigDO.setGroupId(groupId);
                viewConfigDO.setProductId(productId);
                List<ViewConfigDO> viewConfigDOS = viewConfigBizService.list(viewConfigDO);
                return Optional.ofNullable(viewConfigDOS).orElse(Collections.emptyList()).stream().map(v -> {
                    IdeListVO ideListVO = new IdeListVO();
                    ideListVO.setType(d);
                    ideListVO.setData(v);
                    return ideListVO;
                }).toList();
            } else if (d.equals("job")) {
                JobConfigDO jobConfigDO = new JobConfigDO();
                jobConfigDO.setGroupId(groupId);
                jobConfigDO.setProductId(productId);
                List<JobConfigDO> jobConfigDOList = jobConfigBizService.list(jobConfigDO);
                return Optional.ofNullable(jobConfigDOList).orElse(Collections.emptyList()).stream().map(v -> {
                    IdeListVO ideListVO = new IdeListVO();
                    ideListVO.setType(d);
                    ideListVO.setData(v);
                    return ideListVO;
                }).toList();
            } else if (d.equals("api")) {
                ApiConfigDO apiConfigDO = new ApiConfigDO();
                apiConfigDO.setGroupId(groupId);
                apiConfigDO.setProductId(productId);
                List<ApiConfigDO> apiConfigDOList = apiConfigBizService.list(apiConfigDO);
                return Optional.ofNullable(apiConfigDOList).orElse(Collections.emptyList()).stream().map(v -> {
                    IdeListVO ideListVO = new IdeListVO();
                    ideListVO.setType(d);
                    ideListVO.setData(v);
                    return ideListVO;
                }).toList();
            } else if (d.equals("process")) {
                SquareLakeProcessQueryByConditionRequest squareLakeProcessQueryByConditionRequest = new SquareLakeProcessQueryByConditionRequest();
                squareLakeProcessQueryByConditionRequest.setGroupId(groupId);
                squareLakeProcessQueryByConditionRequest.setProductId(productId);
                List<ProcessSimpleVO> processSimpleVOS = processBizService.list(squareLakeProcessQueryByConditionRequest);
                return Optional.ofNullable(processSimpleVOS).orElse(Collections.emptyList()).stream().map(v -> {
                    IdeListVO ideListVO = new IdeListVO();
                    ideListVO.setType(d);
                    ideListVO.setData(v);
                    return ideListVO;
                }).toList();

            } else if (d.equals("processVersion")) {
                List<ProcessVersionVO> processVersionVOList = null;
                if (StrUtil.isNotBlank(processId)) {
                    ProcessVersionDO processVersionDO = new ProcessVersionDO();
                    processVersionDO.setProcessId(processId);
                    processVersionVOList = versionBizService.list(processVersionDO);
                }
                return Optional.ofNullable(processVersionVOList).orElse(Collections.emptyList()).stream().map(v -> {
                    IdeListVO ideListVO = new IdeListVO();
                    ideListVO.setType(d);
                    ideListVO.setData(v);
                    return ideListVO;
                }).toList();
            }

            OfficeRecordDO officeRecordDO = new OfficeRecordDO();
            officeRecordDO.setGroupId(groupId);
            officeRecordDO.setProductId(productId);
            officeRecordDO.setTypeCode(d);
            List<OfficeRecordDO> list = officeRecordBizService.list(officeRecordDO);
            return Optional.ofNullable(list).orElse(Collections.emptyList()).stream().map(v -> {
                IdeListVO ideListVO = new IdeListVO();
                ideListVO.setType(v.getTypeCode());
                ideListVO.setData(v);
                return ideListVO;
            }).collect(Collectors.toList());
        })).collect(Collectors.toList());

        futureList.forEach(d -> {
            try {
                List<IdeListVO> patientSyncDTOS = d.get();
                if (CollUtil.isNotEmpty(patientSyncDTOS)) {
                    result.addAll(patientSyncDTOS);
                }
            } catch (Exception e) {
                log.error("线程获取转换的数据异常", e);
            }
        });

        return result;
    }
}
